﻿using Moq;
using NUnit.Framework;
using Syncfusion.XForms.RichTextEditor;
using System.Collections.ObjectModel;
using System.IO;
using System.Threading.Tasks;
using TabbedTemplate.Models;
using TabbedTemplate.Services;
using TabbedTemplate.ViewModels;

namespace UnitTest.NotTestViewModel
{
    public class TestPunchPageViewModel
    {

        [Test]
        public void TestPageAppearingCommandIsNewPunch()
        {
            var preferenceStorageMock = new Mock<IPreferenceStorage>();
            preferenceStorageMock.Setup(p => p.Get("newPunch", true))
                .Returns(true);
            var mockPreferenceStorage = preferenceStorageMock.Object;
            var punchPageViewModel = new PunchPageViewModel(null, null, null,
                null, null, null, mockPreferenceStorage, null, null);

            var punchTimeStampParameter = new PunchTimeStampParameter
            {
                PunchInfo = new PunchInfo { Content = "测试" }
            };
            punchPageViewModel.PunchTimeStampParameter =
                punchTimeStampParameter;
            punchPageViewModel.PageAppearingCommandFunction();

            Assert.IsTrue(punchPageViewModel.EditorHtmlText == "测试");

        }

        [Test]
        public void TestGetImageIsNull()
        {
            var collection = new ObservableCollection<ImageSource>();
            var e = new ImageInsertedEventArgs(collection);
            var photoPickerServiceMock = new Mock<IPhotoPickerService>();
            Stream imageStream = null;
            photoPickerServiceMock.Setup(p => p.GetImageStreamAsync())
                .ReturnsAsync(imageStream);
            var mockPhotoPickerService = photoPickerServiceMock.Object;
            var punchPageViewModel = new PunchPageViewModel(
                mockPhotoPickerService, null, null, null, null, null, null,
                null, null);

            punchPageViewModel.GetImage(e);
            Assert.IsTrue(collection.Count == 0);
            photoPickerServiceMock.Verify(p => p.GetImageStreamAsync(), Times.Once);
        }

        [Test]
        public void TestGetImageNotNull()
        {
            var collection = new ObservableCollection<ImageSource>();
            var e = new ImageInsertedEventArgs(collection);
            var photoPickerServiceMock = new Mock<IPhotoPickerService>();
            Stream imageStream = new FileStream(@"D:\1.txt", FileMode.Append);
            photoPickerServiceMock.Setup(p => p.GetImageStreamAsync())
                .ReturnsAsync(imageStream);
            var mockPhotoPickerService = photoPickerServiceMock.Object;
            var punchPageViewModel = new PunchPageViewModel(
                mockPhotoPickerService, null, null, null, null, null, null,
                null, null);

            punchPageViewModel.GetImage(e);
            Assert.IsTrue(collection.Count == 1);
            photoPickerServiceMock.Verify(p => p.GetImageStreamAsync(), Times.Once);
            imageStream.Close();
            //清除
            File.Delete(@"D:\1.txt");
        }

        [Test]
        public async Task TestPunchCommandNotInitializePunchStorageAndStoreStorage()
        {
            var alertServiceMock = new Mock<IAlertService>();
            alertServiceMock
                .Setup(p => p.ShowAlert("提示", "是否确认打卡？", "确认", "取消"))
                .ReturnsAsync(true);
            var mockAlertService = alertServiceMock.Object;

            var punchInfoStorageMock = new Mock<IPunchInfoStorage>();
            punchInfoStorageMock.Setup(p => p.PunchInfoStorageInitialized())
                .Returns(false);
            var punchTimeStampParameter = new PunchTimeStampParameter
            {
                Store = new Store
                {
                    Uid = "12324"
                }
            };
            string editorHtmlText = "单元测试";
            var resLong = 1234;
            punchInfoStorageMock.Setup(p => p.InsertPunchInfoAsync(punchTimeStampParameter.Store.Uid, editorHtmlText))
                .ReturnsAsync(resLong);

            var mockPunchInfoStorage = punchInfoStorageMock.Object;

            var storeStorageMock = new Mock<IStoreStorage>();
            storeStorageMock.Setup(p => p.UserCacheInitialized())
                .Returns(false);
            var mockStoreSTorage = storeStorageMock.Object;

            var punchNavigationServiceMock =
                new Mock<IPunchNavigationService>();
            var mockPunchNavigationService = punchNavigationServiceMock.Object;
            var imageServiceMock = new Mock<IImageService>();
            var mockImageService = imageServiceMock.Object;

            var collection = new ObservableCollection<ImageViewModel>();
            var punchPageViewModel = new PunchPageViewModel(null,
                mockAlertService, mockImageService, mockPunchInfoStorage,
                mockStoreSTorage, null, null, null, mockPunchNavigationService);
            punchPageViewModel.ImageSource = new byte[1000];
            punchPageViewModel.EditorHtmlText = editorHtmlText;
            var im = new ImageViewModel(punchPageViewModel, null);
            collection.Add(im);
            punchPageViewModel.ImageViewModelCollection = collection;
            punchPageViewModel.PunchTimeStampParameter =
                punchTimeStampParameter;
            await punchPageViewModel.PunchCommandFunction();

            alertServiceMock.Verify(p => p.ShowAlert("提示", "是否确认打卡？", "确认", "取消"), Times.Once);
            alertServiceMock.Verify(p => p.ShowAlert("提示", "打卡成功!", "确认"), Times.Once);

            punchInfoStorageMock.Verify(p => p.PunchInfoStorageInitializeAsync(), Times.Once);
            punchInfoStorageMock.Verify(p => p.InsertPunchInfoAsync(punchTimeStampParameter.Store.Uid, editorHtmlText), Times.Once);

            storeStorageMock.Verify(p => p.UserCacheInitialized(), Times.Once);
            storeStorageMock.Verify(p => p.UserCacheInitializeAsync(), Times.Once);
            storeStorageMock.Verify(p => p.InsertAStore(punchTimeStampParameter.Store), Times.Once);

            imageServiceMock.Verify(p => p.CreateFolder(resLong), Times.Once);
            imageServiceMock.Verify(p => p.SaveImageAsync(resLong, im.ImageSource, resLong + "-" + 0 + ".png"), Times.Once);
            punchNavigationServiceMock.Verify(p => p.NavigateBack(), Times.Once);
        }

        [Test]
        public async Task TestPunchCommandInitializedPunchStorageAndStoreStorage()
        {
            var alertServiceMock = new Mock<IAlertService>();
            alertServiceMock
                .Setup(p => p.ShowAlert("提示", "是否确认打卡？", "确认", "取消"))
                .ReturnsAsync(true);
            var mockAlertService = alertServiceMock.Object;

            var punchInfoStorageMock = new Mock<IPunchInfoStorage>();
            punchInfoStorageMock.Setup(p => p.PunchInfoStorageInitialized())
                .Returns(true);
            var punchTimeStampParameter = new PunchTimeStampParameter
            {
                Store = new Store
                {
                    Uid = "12324"
                }
            };
            string editorHtmlText = "单元测试";
            var resLong = 1234;
            punchInfoStorageMock.Setup(p => p.InsertPunchInfoAsync(punchTimeStampParameter.Store.Uid, editorHtmlText))
                .ReturnsAsync(resLong);

            var mockPunchInfoStorage = punchInfoStorageMock.Object;

            var storeStorageMock = new Mock<IStoreStorage>();
            storeStorageMock.Setup(p => p.UserCacheInitialized())
                .Returns(true);
            var mockStoreSTorage = storeStorageMock.Object;

            var punchNavigationServiceMock =
                new Mock<IPunchNavigationService>();
            var mockPunchNavigationService = punchNavigationServiceMock.Object;
            var imageServiceMock = new Mock<IImageService>();
            var mockImageService = imageServiceMock.Object;

            var collection = new ObservableCollection<ImageViewModel>();
            var punchPageViewModel = new PunchPageViewModel(null,
                mockAlertService, mockImageService, mockPunchInfoStorage,
                mockStoreSTorage, null, null, null, mockPunchNavigationService);
            punchPageViewModel.ImageSource = new byte[1000];
            punchPageViewModel.EditorHtmlText = editorHtmlText;
            var im = new ImageViewModel(punchPageViewModel, null);
            collection.Add(im);
            punchPageViewModel.ImageViewModelCollection = collection;
            punchPageViewModel.PunchTimeStampParameter =
                punchTimeStampParameter;
            await punchPageViewModel.PunchCommandFunction();

            alertServiceMock.Verify(p => p.ShowAlert("提示", "是否确认打卡？", "确认", "取消"), Times.Once);
            alertServiceMock.Verify(p => p.ShowAlert("提示", "打卡成功!", "确认"), Times.Once);

            punchInfoStorageMock.Verify(p => p.PunchInfoStorageInitializeAsync(), Times.Never);
            punchInfoStorageMock.Verify(p => p.InsertPunchInfoAsync(punchTimeStampParameter.Store.Uid, editorHtmlText), Times.Once);

            storeStorageMock.Verify(p => p.UserCacheInitialized(), Times.Once);
            storeStorageMock.Verify(p => p.UserCacheInitializeAsync(), Times.Never);
            storeStorageMock.Verify(p => p.InsertAStore(punchTimeStampParameter.Store), Times.Once);

            imageServiceMock.Verify(p => p.CreateFolder(resLong), Times.Once);
            imageServiceMock.Verify(p => p.SaveImageAsync(resLong, im.ImageSource, resLong + "-" + 0 + ".png"), Times.Once);
            punchNavigationServiceMock.Verify(p => p.NavigateBack(), Times.Once);
        }

        [Test]
        public async Task TestPicCommand()
        {
            var collection = new ObservableCollection<ImageViewModel>();
            string editorHtmlText = "单元测试";
            var punchNavigationServiceMock =
                new Mock<IPunchNavigationService>();
            var mockPunchNavigationService = punchNavigationServiceMock.Object;
            var punchPageViewModel = new PunchPageViewModel(null, null, null,
                null, null, null, null, null, mockPunchNavigationService);
            punchPageViewModel.ImageSource = new byte[1000];
            punchPageViewModel.EditorHtmlText = editorHtmlText;
            var im = new ImageViewModel(punchPageViewModel, null);
            collection.Add(im);
            punchPageViewModel.ImageViewModelCollection = collection;

            await punchPageViewModel.PicCommandFunction();
        }

        [Test]
        public async Task TestAddImageViewModelImageSourceIsNullByTakePhoto()
        {
            var preferenceStorageMock = new Mock<IPreferenceStorage>();
            var mockPreferenceStorage = preferenceStorageMock.Object;
            var alertServiceMock = new Mock<IAlertService>();
            alertServiceMock.Setup(p => p.ShowAlert("请选择一种方式", "取消", null,
                "拍照", "从本地相册选取一张照片", null)).ReturnsAsync("拍照");
            var mockAlertService = alertServiceMock.Object;
            var pickPhotoServiceMock = new Mock<IPickPhotoService>();
            var mockPickPhotoService = pickPhotoServiceMock.Object;
            var punchPageViewModel = new PunchPageViewModel(null, mockAlertService, null,
                null, null, mockPickPhotoService, mockPreferenceStorage, null, null);
            var imageViewModel = new ImageViewModel(punchPageViewModel, null);

            await punchPageViewModel.AddImageViewModel(imageViewModel);

            preferenceStorageMock.Verify(p => p.Set("newPunch", false), Times.Once);
            alertServiceMock.Verify(p => p.ShowAlert("请选择一种方式", "取消", null,
                "拍照", "从本地相册选取一张照片", null), Times.Once);
            pickPhotoServiceMock.Verify(p => p.TakePhotoAsync(), Times.Once);
        }

        [Test]
        public async Task TestAddImageViewModelImageSourceIsNullByPickFromPhotoGallery()
        {
            var preferenceStorageMock = new Mock<IPreferenceStorage>();
            var mockPreferenceStorage = preferenceStorageMock.Object;
            var alertServiceMock = new Mock<IAlertService>();
            alertServiceMock.Setup(p => p.ShowAlert("请选择一种方式", "取消", null,
                "拍照", "从本地相册选取一张照片", null)).ReturnsAsync("从本地相册选取一张照片");
            var mockAlertService = alertServiceMock.Object;
            var pickPhotoServiceMock = new Mock<IPickPhotoService>();
            var mockPickPhotoService = pickPhotoServiceMock.Object;
            var punchPageViewModel = new PunchPageViewModel(null, mockAlertService, null,
                null, null, mockPickPhotoService, mockPreferenceStorage, null, null);
            var imageViewModel = new ImageViewModel(punchPageViewModel, null);

            await punchPageViewModel.AddImageViewModel(imageViewModel);

            preferenceStorageMock.Verify(p => p.Set("newPunch", false), Times.Once);
            alertServiceMock.Verify(p => p.ShowAlert("请选择一种方式", "取消", null,
                "拍照", "从本地相册选取一张照片", null), Times.Once);
            pickPhotoServiceMock.Verify(p => p.PickPhotoAsync(), Times.Once);
        }

        /// <summary>
        /// 删除后还剩余图片。
        /// </summary>

        [Test]
        public void TestRemoveImageViewModelImageViewModelCollectionNotEmptyAfter()
        {
            var preferenceStorageMock = new Mock<IPreferenceStorage>();
            var mockPreferenceStorage = preferenceStorageMock.Object;
            var collection = new ObservableCollection<ImageViewModel>();

            var punchPageViewModel = new PunchPageViewModel(null, null, null,
                null, null, null, mockPreferenceStorage, null, null);
            punchPageViewModel.ImageSource = new byte[1000];
            var im = new ImageViewModel(punchPageViewModel, null);
            collection.Add(im);
            punchPageViewModel.ImageSource = new byte[2000];
            punchPageViewModel.IsVisualCollectionView = true;
            var im2 = new ImageViewModel(punchPageViewModel, null);
            collection.Add(im2);
            punchPageViewModel.ImageViewModelCollection = collection;
            punchPageViewModel.RemoveImageViewModel(im);
            Assert.IsTrue(punchPageViewModel.IsVisualCollectionView);
        }

        /// <summary>
        /// 删除后不再剩余图片。
        /// </summary>
        [Test]
        public void TestRemoveImageViewModelImageViewModelCollectionIsEmptyAfter()
        {
            var preferenceStorageMock = new Mock<IPreferenceStorage>();
            var mockPreferenceStorage = preferenceStorageMock.Object;
            var collection = new ObservableCollection<ImageViewModel>();

            var punchPageViewModel = new PunchPageViewModel(null, null, null,
                null, null, null, mockPreferenceStorage, null, null);
            punchPageViewModel.ImageSource = new byte[1000];
            var im = new ImageViewModel(punchPageViewModel, null);
            collection.Add(im);
            punchPageViewModel.ImageSource = new byte[2000];
            punchPageViewModel.IsVisualCollectionView = true;
            punchPageViewModel.ImageViewModelCollection = collection;
            punchPageViewModel.RemoveImageViewModel(im);
            Assert.IsFalse(punchPageViewModel.IsVisualCollectionView);
        }
    }
}
